package com.shiro.shiroweb.auth;


import com.shiro.shiroweb.entity.UserEntity;
import com.shiro.shiroweb.service.LoginService;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;

import java.util.Set;

/**
 * 自定义Realm(校验逻辑)
 */
@Log4j2
public class CustomRealm extends AuthorizingRealm {
    @Value(value = "${shiro.salt}")
    private String salt;
    @Autowired
    private LoginService loginService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("---------------- 执行 Shiro 权限获取 ---------------------");
        String username = (String) principalCollection.getPrimaryPrincipal();
        Set<String> roles=getReolseByUsername(username);
        Set<String> permissions=getPermissionsByUsername(username);
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);
        log.info("---------------- 角色:"+simpleAuthorizationInfo.getRoles().toString());
        log.info("---------------- 权限:"+simpleAuthorizationInfo.getStringPermissions().toString());
        log.info("---------------- 结束 Shiro 权限获取 ---------------------");
        return simpleAuthorizationInfo;
    }

    private Set<String> getPermissionsByUsername(String username) {
        return loginService.findPermissionByUsername(username);
    }

    private Set<String> getReolseByUsername(String username) {
        return loginService.findRolesByUsername(username);
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("---------------- 执行 Shiro 凭证认证 ---------------------");
        UsernamePasswordToken token =(UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        if(StringUtils.isEmpty(username)){
            throw new AccountException("没有对应账户");
        }
        UserEntity user = loginService.findByName(username);
        if(user==null){
            throw new AccountException("没有对应账户");
        }
        SimpleAuthenticationInfo authenticationInfo=new SimpleAuthenticationInfo(user.getName(),user.getPassword(),getName());
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(salt));
        log.info("---------------- 结束 Shiro 凭证认证 ---------------------");
        return authenticationInfo;
    }
}
